package com.yc.cloud.common.basic.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import lombok.val;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


public class MyFileUtils {

    public static final List<String> IMAGE_SUFFIX = Arrays.asList("jpg", "png", "bmp", "jpeg");
    public static final List<String> VIDEO_SUFFIX = Arrays.asList("mp4", "avi", "wmv", "mov", "mpeg");
    public static final List<String> MODEL_SUFFIX = Arrays.asList("gltf", "glb");
    public static final List<String> AUDIO_SUFFIX = Arrays.asList("mp3", "wav", "wma", "aac", "mov");
    private static final List<String> EXCEL_SUFFIX = Arrays.asList("xlsx", "xls");
    private static final List<String> ZIP_SUFFIX = List.of("zip");


    /**
     * 方式二
     * 该方式支持本地文件，也支持http/https远程文件
     *
     * @param path
     */
    @SneakyThrows
    public static String getContentType(String path) {
//        Tika tika = new Tika();
//        return tika.detect(path);
        return Files.probeContentType(Paths.get(path));
    }

    public static boolean isZip(String fileName) {
        val suffix = FileUtil.getSuffix(fileName).toLowerCase();
        return ZIP_SUFFIX.contains(suffix);
    }

    public static boolean isImage(String fileName) {
        val suffix = FileUtil.getSuffix(fileName).toLowerCase();
        return IMAGE_SUFFIX.contains(suffix);
    }

    public static boolean isVideo(String fileName) {
        val suffix = FileUtil.getSuffix(fileName).toLowerCase();
        return VIDEO_SUFFIX.contains(suffix);
    }

    public static boolean isModel(String fileName) {
        val suffix = FileUtil.getSuffix(fileName).toLowerCase();
        return MODEL_SUFFIX.contains(suffix);
    }

    public static boolean isAudio(String fileName) {
        val suffix = FileUtil.getSuffix(fileName).toLowerCase();
        return AUDIO_SUFFIX.contains(suffix);
    }

    public static boolean isExcel(String fileName) {
        val suffix = FileUtil.getSuffix(fileName).toLowerCase();
        return EXCEL_SUFFIX.contains(suffix);
    }


    public static boolean isMaterial(String fileName) {
        if (isImage(fileName) || isModel(fileName) || isVideo(fileName) || isAudio(fileName)) {
            return true;
        }
        return false;
    }

    public static boolean isSupport(String fileName) {
        if (isImage(fileName) || isModel(fileName) || isVideo(fileName) || isAudio(fileName) || isZip(fileName)) {
            return true;
        }
        return false;
    }

    /**
     * Description 文件转字节数组
     * Create By Mr.Fang
     *
     * @param path 文件路径
     * @return byte[] 字节数组
     * @time 2022/7/10 10:55
     **/
    public static byte[] fileToBytes(String path) {
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            bos = new ByteArrayOutputStream();
            fis = new FileInputStream(path);
            int temp;
            byte[] bt = new byte[1024 * 10];
            while ((temp = fis.read(bt)) != -1) {
                bos.write(bt, 0, temp);
            }
            bos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (Objects.nonNull(fis)) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bos.toByteArray();
    }

    public static String convertFileSize(long size) {
        if (size <= 0) {
            return "0 B";
        }
        final String[] units = {"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));

        DecimalFormat decimalFormat = new DecimalFormat("#,##0.#");
        return decimalFormat.format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }

    public static double bytesToGB(long bytes) {
        return bytes / (1024.0 * 1024 * 1024);
    }

    public static String bytesToGB(long bytes, int decimalPlaces) {
        // 将字节转换为以千为单位的千兆字节（GB）
        double gigabytes = bytes / (1000.0 * 1000 * 1000);
        // 构建格式模式，确保至少有一位整数部分
        StringBuilder pattern = new StringBuilder("0."); // 确保至少显示整数部分

        // 添加指定的小数位数
        for (int i = 0; i < decimalPlaces; i++) {
            pattern.append("0");
        }

        // 创建格式化对象
        DecimalFormat df = new DecimalFormat(pattern.toString());
        return df.format(gigabytes); // 返回格式化后的字符串
    }


    public static List<File> filterFilesBySuffix(List<File> files, String suffix) {
        return files.stream().filter(file -> FileUtil.getSuffix(file).equalsIgnoreCase(suffix)).collect(Collectors.toList());
    }

    /**
     * 按照后缀集合进行文件过滤
     *
     * @param files      文件集合
     * @param suffixList 符合的后缀集合列表
     * @return 过滤后的文件列表
     */
    public static List<File> filterFilesBySuffixList(List<File> files, List<String> suffixList) {
        if (CollUtil.isEmpty(suffixList)) {
            return files;
        }
        return files.stream().filter(file -> suffixList.contains(FileUtil.getSuffix(file))).collect(Collectors.toList());
    }

    public static String convertToBase64(MultipartFile file) {
        String base64 = "";
        try {
            byte[] fileContent = file.getBytes(); // 获取文件的字节内容
            base64 = Base64.getEncoder().encodeToString(fileContent); // 将字节内容编码为Base64字符串
        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
        }
        return base64;
    }

    public static String convertToBase64(File file) {
        try {
            // 读取文件为字节数组
            byte[] fileContent = Files.readAllBytes(file.toPath());
            // 使用Base64类编码字节数组
            return Base64.getEncoder().encodeToString(fileContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void decodeAndSaveFile(String base64AudioData, String outputPath) {
        if (StrUtil.isEmpty(base64AudioData)) {
            return;
        }
        //String outputAudioFile = "/Users/jackgu/Downloads/tts.mp3";
        // 解码Base64数据
        byte[] audioData = Base64.getDecoder().decode(base64AudioData);
        // 将解码后的数据写入到音频文件
        FileUtil.writeBytes(audioData, outputPath);
    }

    public static void cleanDirectoryExcept(File rootDir, List<String> excludeDirs) throws IOException {
        if (rootDir == null || !rootDir.isDirectory()) {
            throw new IllegalArgumentException("Root directory is not valid");
        }

        // 列出所有子文件和子目录
        File[] files = rootDir.listFiles();
        if (files == null) {
            return;
        }

        for (File file : files) {
            // 如果是目录且在排除列表中，跳过删除
            if (file.isDirectory() && excludeDirs.contains(file.getName())) {
                continue;
            }

            // 如果是文件或不在排除列表中的目录，进行删除
            FileUtils.forceDelete(file);
        }
    }

    public static String getVideoExtension(String url) {
        // 定义支持的视频格式
        String regex = "\\.(mp4|avi|mkv|mov|wmv|flv|webm|mpeg|mpg)(\\?.*)?$";
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(url);

        if (matcher.find()) {
            return matcher.group(1); // 返回扩展名
        }
        return null; // 未找到扩展名
    }


}
